home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / mawk10.zip / GDECL.AWK < prev    next >
Text File  |  1991-10-05  |  3KB  |  137 lines

  1.  
  2. # parse a C declaration by recursive descent
  3. #  decl.awk with extra escapes \
  4.  
  5. ################################################
  6. ############################################
  7.  
  8.  
  9. #   lexical scanner -- gobble()
  10. #   input : string s -- treated as a regular expression
  11. #   gobble eats SPACE, then eats longest match of s off front
  12. #   of global variable line.
  13. #   Cuts the matched part off of line
  14. #
  15.  
  16.  
  17. function gobble(s,  x)  
  18. {
  19.   sub( /^ /, "", line)  # eat SPACE if any
  20.  
  21.   # surround s with parenthesis to make sure ^ acts on the
  22.   # whole thing
  23.  
  24.   match(line, "^" "(" s ")")
  25.   x = substr(line, 1, RLENGTH)
  26.   line = substr(line, RLENGTH+1)
  27.   return x 
  28. }
  29.  
  30.  
  31. function ptr_to(n,  x)  # print "pointer to" , n times
  32. { n = int(n)
  33.   if ( n <= 0 )  return ""
  34.   x = "pointer to" ; n--
  35.   while ( n-- )  x = x " pointer to"
  36.   return x
  37. }
  38.  
  39.  
  40. #recursively get a decl
  41. # returns an english description of the declaration or
  42. # "" if not a C declaration.
  43.  
  44. function  decl(   x, t, ptr_part)
  45. {
  46.  
  47.   x = gobble("[* ]+")   # get list of *** ...
  48.   gsub(/ /, "", x)   # remove all SPACES
  49.   ptr_part = ptr_to( length(x) )
  50.  
  51.   # We expect to see either an identifier or '('
  52.   #
  53.  
  54.   if ( gobble("\\(") )
  55.   { 
  56.     # this is the recursive descent part
  57.     # we expect to match a declaration and closing ')'
  58.     # If not return "" to indicate  failure
  59.  
  60.       if ( (x = decl()) == "" || gobble( "\\)" ) == "" ) return ""
  61.  
  62.   }
  63.   else  #  expecting an identifier
  64.   {
  65.     if ( (x = gobble(id)) == "" )  return ""
  66.     x = x ":"
  67.   }
  68.  
  69.   # finally look for ()
  70.   # or  [ opt_size ]
  71.  
  72.   while ( 1 )
  73.      if ( gobble( funct_mark ) )  x = x " function returning"
  74.      else
  75.      if ( t = gobble( array_mark ) )
  76.      { gsub(/ /, "", t)
  77.        x = x " array" t " of"
  78.      }
  79.      else  break
  80.  
  81.  
  82.    x = x " "  ptr_part
  83.    return x
  84. }
  85.     
  86.  
  87. BEGIN { id = "[_A-Za-z][_A-Za-z0-9]*" 
  88.         funct_mark = "\\([ \t]*\\)"
  89.     array_mark = "\\[[ \t]*[_A-Za-z0-9]*[ \t]*\\]"
  90.  
  91. # I've assumed types are keywords or all CAPS or end in _t
  92. # Other conventions could be added.
  93.  
  94.     type0 = "int|char|short|long|double|float|void" 
  95.     type1 = "[_A-Z][_A-Z0-9]*"  #  types are CAPS
  96.     type2 = "[_A-Za-z][_A-Za-z0-9]*_t"  # end in _t
  97.  
  98.     types = "(" type0 "|" type1 "|" type2 ")"
  99. }
  100.  
  101.  
  102. {   
  103.  
  104.     gsub( /\/\*([^*]|\*[^\/])*(\*\/|$)/ , " ") # remove comments
  105.     gsub( /[ \t]+/, " ")  # squeeze white space to a single space
  106.  
  107.  
  108.     line = $0
  109.  
  110.     scope = gobble( "extern|static" )
  111.  
  112.     if ( type = gobble("(struct|union|enum) ") )
  113.             type = type gobble(id)  #  get the tag
  114.     else
  115.     {
  116.  
  117.        type = gobble("(un)?signed ") gobble( types )
  118.  
  119.     }
  120.     
  121.     if ( ! type )  next
  122.     
  123.     if ( (x = decl()) && gobble( ";") )
  124.     {
  125.       x  =  x " " type
  126.       if ( scope )  x = x " (" scope ")"
  127.       gsub( /  +/, " ", x)  # 
  128.       print x
  129.     }
  130.  
  131. }
  132.  
  133.  
  134.  
  135.  
  136.